package org.xiaov.lunasql.engine.function;

import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;

import java.util.List;

/**
 * <p>
 * ConcatWsFunc
 * </p>
 *
 * @author LunaSQL
 * @since 2024/12/15 22:37
 */
public class ConcatWsFunc implements MySqlFunction {
    private final static String METHOD_NAME = "concat_ws";
    private final List<MySqlFunction> functions;

    /**
     * ConcatWsFunc
     *
     * @param functions functions
     */
    public ConcatWsFunc(List<MySqlFunction> functions) {
        this.functions = functions;
    }

    @Override
    public boolean accept(SQLMethodInvokeExpr methodInvokeExpr) {
        return METHOD_NAME.equalsIgnoreCase(methodInvokeExpr.getMethodName());
    }

    @Override
    public void transform(SQLMethodInvokeExpr methodInvokeExpr) {
        SQLObject parent = methodInvokeExpr.getParent();
        SQLExpr symbol = methodInvokeExpr.getArgument(0);

        List<SQLExpr> arguments = methodInvokeExpr.getArguments();
        StringBuilder ws = new StringBuilder();
        for (int i = 1; i < arguments.size(); i++) {
            SQLExpr argument = arguments.get(i);
            if (argument instanceof SQLMethodInvokeExpr method) {
                for (MySqlFunction function : functions) {
                    if (function.accept(method)) {
                        function.transform(method);
                    }
                }
            }
            ws.append(argument.toString());
            if (i != arguments.size() - 1) {
                ws.append(" || ").append(symbol.toString()).append(" || ");
            }
        }
        SQLIdentifierExpr sqlIdentifierExpr = new SQLIdentifierExpr(ws.toString());
        if (parent instanceof SQLReplaceable replaceable) {
            replaceable.replace(methodInvokeExpr, sqlIdentifierExpr);
        }

    }
}
